﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class BattleEntityHero : BattleEntity
{
    public int m_iMaxHp = 0;
    public int m_iHp = 0;
    public GameObject m_pGameObj;
    public GameObject m_pGameSkele;
    public SkeletonAnimation m_pSkele;
    public Renderer m_pRender;
    public MoveComp m_pMoveComp;
    public HeroVo m_pHeroVo;
    public NStateMachine<BattleEntityHero> m_pStateMachine;


    //实体身上的计时器,某些情况下要提前清空
    private List<int> m_lisTimerIds = new List<int>();

    //组织方法
    public NGUIDebugLabel m_pDebugLab;
    public override void OnCreate(params object[] args)
    {
        m_pHeroVo = (HeroVo)args[0];
        m_iHp = m_pHeroVo.initHp;
        m_iMaxHp = m_pHeroVo.initHp;
        //创建U3D对象 模型等
        m_pGameObj = new GameObject();
        m_pGameObj.name = "Entity_Hero_" + m_pHeroVo.index.ToString()+"_"+m_pHeroVo.reportId;
        m_pGameObj.transform.position = HeroFightUtil.GetPosByIndex(m_pHeroVo.index);
        m_pGameSkele = GameObject.Instantiate<GameObject>(HeroBattleMgr.Instance.m_DicSpines[m_pHeroVo.model]);
        m_pGameSkele.transform.SetParent(m_pGameObj.transform);
        m_pGameSkele.transform.localPosition = Vector3.zero;
        m_pGameSkele.transform.localEulerAngles = Vector3.zero;
        m_pGameSkele.transform.localScale = Vector3.one;
        m_pMoveComp = new MoveComp(m_pGameObj.transform, this);
        //m_pMoveComp.m_fMaxSpeed = m_pHeroVo.m_pConfig.maxSpeed;

        //Spine 相关初始化
        m_pSkele = m_pGameSkele.GetComponent<SkeletonAnimation>();
        m_pSkele.ignoreTimeScale = true;
        m_pSkele.skeleton.FlipX = m_pHeroVo.m_bFilp;
        m_pSkele.state.Event += HandleSpine_Event;
        m_pSkele.state.Start += HandleSpine_Start;
        m_pSkele.state.End += HandleSpine_End;
        m_pSkele.state.Complete += HandleSpine_Comp;
        m_pRender = m_pGameSkele.GetComponent<Renderer>();


        //状态机
        Dictionary<string, NState<BattleEntityHero>> states = new Dictionary<string, NState<BattleEntityHero>>()
        {
            {BattleHeroState.c_sMState_Action,BattleHeroState.s_pMState_Action},
            {BattleHeroState.c_sMState_Hit,BattleHeroState.s_pMState_Hit },
            {BattleHeroState.c_sMState_Idle,BattleHeroState.s_pMState_Idle },
            {BattleHeroState.c_sMState_Move,BattleHeroState.s_pMState_Move },
            {BattleHeroState.c_sMState_Global,BattleHeroState.s_pMState_Global },
            {BattleHeroState.c_sMState_Dead,BattleHeroState.s_pMState_Dead },
            {BattleHeroState.c_sMState_Win,BattleHeroState.s_pMState_Win }
        };
        m_pStateMachine = new NStateMachine<BattleEntityHero>(this,states,BattleHeroState.c_sMState_Global);
        m_pStateMachine.ChangeState(BattleHeroState.c_sMState_Idle);

        //打印工具
        //m_pDebugLab = m_pGameObj.AddComponent<NGUIDebugLabel>();
        //m_pDebugLab.SetTage(m_pGameObj.transform);
    }

    public override bool HandleMessage(MessageBody body)
    {
        return m_pStateMachine.OnHandleMessage(body);
    }

    public override void OnUpdate(float deltaTime)
    {
        base.OnUpdate(deltaTime);
        m_pStateMachine.OnUpdate();
        m_pMoveComp.OnUpdate(deltaTime);
        //Spine网格渲染
        m_pSkele.timeScale = HeroBattleMgr.Instance.Speed;
    }

    public override void OnDestroy()
    {
        //清楚身上的特效
        BattleEffectMgr.Instance.DelEntityAllEffObj(Id);
    }

    //播放动画
    public void PlayAction(string actionId, bool bLoop = false)
    {
        if (actionId == "0")
            return;

        m_pSkele.loop = bLoop;
        m_pSkele.AnimationName = actionId;
    }

    public void ChangeState(string state,params object[] args)
    {
        m_pStateMachine.ChangeState(state,args);
        //m_pDebugLab.Content = m_pStateMachine.CurrentState;
        HeroFightUtil.SetSpineOrderState(state, this);
    }

    public bool IsInState(string state)
    {
        return m_pStateMachine.IsInState(state);
    }

    //Spine事件
    private void HandleSpine_Event(Spine.AnimationState state, int trackIndex, Spine.Event e)
    {
        //Debug.Log("Event");
    }
    private void HandleSpine_Start(Spine.AnimationState state, int trackIndex)
    {
        //Debug.Log("Start");
    }
    private void HandleSpine_End(Spine.AnimationState state, int trackIndex)
    {
        //Debug.Log("End");
    }
    private void HandleSpine_Comp(Spine.AnimationState state, int trackIndex, int loopCount)
    {
        //Debug.Log("Comp_ " + state.GetCurrent(trackIndex).Animation.Name);

        EntityMessageDispatcher.Instance.SendMessage(state.GetCurrent(trackIndex).Animation.Name, Id, Id);
    }

    public void AddEntityTimer(System.Action action,float delay)
    {
        int id = HeroBattleMgr.Instance.AddTimer(action, delay,"Send hit");
        m_lisTimerIds.Add(id);
    }
    public void ClearAllTimer()
    {
        for(int i = 0; i < m_lisTimerIds.Count; i++)
        {
            HeroBattleMgr.Instance.DelTimer(m_lisTimerIds[i]);
        }
        m_lisTimerIds.Clear();
    }
    public void ClearTimer(int id)
    {
        HeroBattleMgr.Instance.DelTimer(id);
        m_lisTimerIds.Remove(id);
    }

    //重置面朝方向
    public void InitRenderDir()
    {
        m_pSkele.skeleton.FlipX = m_pHeroVo.m_bFilp;
    }

    //是否在初始位置
    public bool IsInInitPos()
    {
        float dis = Vector3.Distance(m_pGameObj.transform.position, HeroFightUtil.GetPosByIndex(m_pHeroVo.index));
        return dis < HeroFightDef.c_fIgnoreOffset;
    }

    //回到初始位置
    public void BackInitPos(string clipName)
    {
        ChangeState(BattleHeroState.c_sMState_Move, MoveComp.moveType.Uniform,
                           clipName, true, 10.0f, HeroFightUtil.GetPosByIndex(m_pHeroVo.index));
    }
    public void BackInitPos()
    {
        BackInitPos(HeroFightDef.c_sAction_Run);
    }

    public void HpChange(int val)
    {
        m_iHp += val;
        if (m_iHp <= 0)
        {
            m_iHp = 0;
        }
    }
    public bool IsDead()
    {
        return m_iHp <= 0;
    }
    public bool IsSerious()
    {
        return (((float)m_iHp) / ((float)m_iMaxHp)) <= HeroFightDef.c_fSerious;
    }
}


public class BattleHeroState
{
    public const string c_sMState_Global = "mglobal";

    public const string c_sMState_Action = "maction";
    public const string c_sMState_Hit = "mhit";
    public const string c_sMState_Idle = "midle";
    public const string c_sMState_Move = "mmove";
    public const string c_sMState_Dead = "mdead";
    public const string c_sMState_Win = "mwin";
    public static MGlobal s_pMState_Global = new MGlobal();
    public static MAction s_pMState_Action = new MAction();
    public static MHit s_pMState_Hit = new MHit();
    public static MIdle s_pMState_Idle = new MIdle();
    public static MMove s_pMState_Move = new MMove();
    public static MDead s_pMState_Dead = new MDead();
    public static MWin s_pMState_Win = new MWin();
}

